package com.example.tcp2504.MultithreadingExample;

// 导入必要的 Java I/O 和网络库
import java.io.*;
import java.net.Socket;

// 定义一个名为 FileTransferTask 的类，它实现了 Runnable 接口，使其可被线程执行
public class FileTransferTask implements Runnable {
    // 定义类的成员变量
    private String serverAddress;   // 服务器地址
    private int serverPort;         // 服务器端口号
    private String filePath;        // 要传输的文件路径
    private TransferProgress progress; // 用于跟踪文件传输进度的对象

    // 构造函数，用于创建一个新的 FileTransferTask 实例
    public FileTransferTask(String serverAddress, int serverPort, String filePath, TransferProgress progress) {
        this.serverAddress = serverAddress; // 初始化服务器地址
        this.serverPort = serverPort;      // 初始化服务器端口号
        this.filePath = filePath;          // 初始化文件路径
        this.progress = progress;          // 初始化传输进度跟踪对象
    }

    // 实现 Runnable 接口的 run 方法，定义任务执行的逻辑
    @Override
    public void run() {
        // 创建一个 File 对象，用于表示要传输的文件
        File file = new File(filePath);
        // 获取文件的大小（字节）
        long fileSize = file.length();
        // 设置传输进度的总字节数
        progress.setTotal(fileSize);

        // 使用 try-with-resources 语句创建 Socket、输入流和输出流，确保它们在使用后自动关闭
        try (
                // 创建一个连接到指定服务器地址和端口的 Socket
                Socket socket = new Socket(serverAddress, serverPort);
                // 创建一个从文件读取数据的输入流
                InputStream inputStream = new FileInputStream(file);
                // 获取 Socket 的输出流，用于向服务器发送数据
                OutputStream outputStream = socket.getOutputStream();
        ) {
            // 创建一个 4096 字节大小的缓冲区，用于读取和写入数据
            byte[] buffer = new byte[4096];
            int bytesRead;          // 用于存储每次从输入流读取的字节数
            long totalBytesRead = 0; // 用于累计已传输的字节数

            // 从文件输入流中读取数据直到文件末尾
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                // 将读取的数据写入到 Socket 的输出流，发送给服务器
                outputStream.write(buffer, 0, bytesRead);
                // 累计已传输的字节数
                totalBytesRead += bytesRead;
                // 更新传输进度的已传输字节数
                progress.setTransferred(totalBytesRead);
            }
            // 刷新输出流，确保所有数据都被发送
            outputStream.flush();
        } catch (IOException e) {
            // 捕获并打印 I/O 异常堆栈信息
            e.printStackTrace();
        }
    }
}
